package com.zb.excel.importExcel.listener;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zb.constant.CodeConstant;
import com.zb.constant.RedisImportDataConstant;
import com.zb.constant.WorkConstant;
import com.zb.entity.*;
import com.zb.excel.OrderExcelImport;
import com.zb.extend.CodeLogExtend;
import com.zb.redis.RedisUtil;
import com.zb.secure.BCryptUtil;
import com.zb.service.*;
import com.zb.service.impl.WorkServiceLog;
import com.zb.utils.*;
import com.zb.view.ViewGoods;
import com.zb.view.ViewNetworkEmpDetail;
import com.zb.vo.WorkLogVo;
import com.zb.websocket.server.ProgressWebSocketServer;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Author WEN
 * @Date 2024/3/13 0013
 **/
public class OrderExcelImportListener implements ReadListener<OrderExcelImport> {
    private static final Logger logger = LoggerFactory.getLogger(OrderExcelImportListener.class);
    private static int BATCH_COUNT = 100; // 每批次执行插入数据库数量
    private boolean isFirstSend; // 是否首次发送进度
    private boolean isTwoSend; // 是否二次发送进度
    private boolean isEndSend; // 是否最后一次发送进度
    private int excelTotalRowCount; // Excel总数量（此包含空行的数量）
    private int totalCount; // 导入的总数量
    private int batch_no; // 导入的批次号
    private long currentExcuteCount; // 当前执行的数量
    private Long codeBatchId; // 批次ID
    private Long codebatchGoodsId; // 批次商品ID
    private List<OrderExcelImport> importFailt;
    private StringBuffer message;
    // 校验数据重复的缓存key
    private String check_data_repeat_key;
    private String code_batch_goods_data_key; // 批次编码商品的缓存Key，表示一个Excel导入算一个批次
    private String CACHE_IMPORT_DATA_REDIS_KEY;

    private String progressUuid; // 进度uuid识别码
    private AccounLoginInfo loginInfo;
    private ZjUserSet userSet; // 客户设置
    private ZjCodeSet codeSet; // 编码设置
    private ZjCode globalCode; // 全局编码对象，无需初始化

    private PlatformTransactionManager transactionManager;
    private ZjCodeBatchService codeBatchService;
    private ZjCodeService codeService;
    private ZjCodeUserRegisterService codeUserRegisterService;
    private ZjUserService userService;
    private ZjUserContactService userContactService;
    private ZjWorkLevelService workLevelService;
    private ZjWorkOrderService workOrderService;
    private ZjWorkDetailService workDetailService;
    private ZjWorkUserService workUserService;
    private ZjWorkGoodsService workGoodsService;
    private ZjWorkGoodsCodeService workGoodsCodeService;
    private ZjWorkDispatchNetworkService workDispatchNetworkService;
    private ZjWorkDispatchEngineerService workDispatchEngineerService;

    private List<ZjUser> userList;
    private List<ZjUserContact> userContactList;
    private List<ZjWorkLevel> workLevelList;
    private List<ZjCode> addCodeList;
    private List<ZjCode> updateCodeList;
    private List<ZjCodeInfo> addCodeInfoList;
    private List<ZjCodeInfo> updateCodeInfoList;
    private List<ZjCodeUserRegister> userRegisterList;
    private List<ZjCodeLog> codeLogList;
    private List<ZjCodeBatch> addCodeBatchList;
    private List<ZjCodeBatch> updateCodeBatchList;
    private List<ZjCodeBatchGoods> addCodeBatchGoodsList;
    private List<ZjCodeBatchGoods> updateCodeBatchGoodsList;
    private List<ZjWorkOrder> orderList;
    private List<ZjWorkDetail> workDetailList;
    private List<ZjWorkUser> workUserList;
    private List<ZjWorkGoods> workGoodsList;
    private List<ZjWorkGoodsCode> workGoodsCodeList;
    private List<ZjWorkDispatchNetwork> dispatchNetworkList;
    private List<ZjWorkDispatchEngineer> dispatchEngineerList;
    private List<WorkLogVo> logVos;
    private List<WorkLogVo> networkLogVos;

    public OrderExcelImportListener(String progressUuid, AccounLoginInfo loginInfo, ZjUserSet userSet, ZjCodeSet codeSet,
                                    PlatformTransactionManager transactionManager, ZjCodeBatchService codeBatchService, ZjCodeService codeService, ZjCodeUserRegisterService codeUserRegisterService,
                                    ZjUserService userService, ZjUserContactService userContactService, ZjWorkLevelService workLevelService,
                                    ZjWorkOrderService workOrderService, ZjWorkDetailService workDetailService, ZjWorkUserService workUserService, ZjWorkGoodsService workGoodsService,
                                    ZjWorkGoodsCodeService workGoodsCodeService, ZjWorkDispatchNetworkService workDispatchNetworkService, ZjWorkDispatchEngineerService workDispatchEngineerService) {
        this.isFirstSend = true;
        this.isTwoSend = true;
        this.isEndSend = false;
        this.excelTotalRowCount = 0;
        this.totalCount = 0;
        this.batch_no = 0;
        this.currentExcuteCount = 0;
        this.importFailt = new ArrayList<>();
        this.message = new StringBuffer();
        this.check_data_repeat_key = RedisImportDataConstant.ORDER_IMPORT + "check-order-data-repeat:" + loginInfo.getCustAccId() + ":" + progressUuid;
        this.code_batch_goods_data_key = RedisImportDataConstant.ORDER_IMPORT + "code-batch-goods-data:" + loginInfo.getCustAccId() + ":" + progressUuid;
        this.CACHE_IMPORT_DATA_REDIS_KEY = RedisImportDataConstant.ORDER_IMPORT + loginInfo.getCustAccId() + progressUuid;

        this.progressUuid = progressUuid;
        this.loginInfo = loginInfo;
        this.userSet = userSet;
        this.codeSet = codeSet;

        this.transactionManager = transactionManager;
        this.codeBatchService = codeBatchService;
        this.codeService = codeService;
        this.codeUserRegisterService = codeUserRegisterService;
        this.userService = userService;
        this.userContactService = userContactService;
        this.workLevelService = workLevelService;
        this.workOrderService = workOrderService;
        this.workDetailService = workDetailService;
        this.workUserService = workUserService;
        this.workGoodsService = workGoodsService;
        this.workGoodsCodeService = workGoodsCodeService;
        this.workDispatchNetworkService = workDispatchNetworkService;
        this.workDispatchEngineerService = workDispatchEngineerService;
        initData();
    }

    // 初始化数据
    private void initData() {
        this.userList = new ArrayList<>();
        this.userContactList = new ArrayList<>();
        this.workLevelList = new ArrayList<>();
        this.addCodeList = new ArrayList<>();
        this.updateCodeList = new ArrayList<>();
        this.addCodeInfoList = new ArrayList<>();
        this.updateCodeInfoList = new ArrayList<>();
        this.userRegisterList = new ArrayList<>();
        this.codeLogList = new ArrayList<>();
        this.addCodeBatchList = new ArrayList<>();
        this.updateCodeBatchList = new ArrayList<>();
        this.addCodeBatchGoodsList = new ArrayList<>();
        this.updateCodeBatchGoodsList = new ArrayList<>();
        this.orderList = new ArrayList<>();
        this.workDetailList = new ArrayList<>();
        this.workUserList = new ArrayList<>();
        this.workGoodsList = new ArrayList<>();
        this.workGoodsCodeList = new ArrayList<>();
        this.dispatchNetworkList = new ArrayList<>();
        this.dispatchEngineerList = new ArrayList<>();
        this.logVos = new ArrayList<>();
        this.networkLogVos = new ArrayList<>();
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        this.excelTotalRowCount = context.readSheetHolder().getApproximateTotalRowNumber();
        this.totalCount = this.excelTotalRowCount -3;
        if (this.isFirstSend) {
            this.message.append("数据正在解析中，请稍等...").append("</br>");
            ProgressWebSocketServer.send(this.progressUuid, false,  new ArrayList(), this.message.toString());
            this.isFirstSend = false;
        }
    }

    @Override
    public void invoke(OrderExcelImport orderExcelImport, AnalysisContext analysisContext) {
        if (this.isTwoSend) {
            this.message.append("数据解析成功，正在导入中..").append("</br>");
            ProgressWebSocketServer.send(this.progressUuid, false,  new ArrayList(), this.message.toString());
            this.isTwoSend = false;
        }
        this.currentExcuteCount++;
        analysisContext.readWorkbookHolder().setIgnoreEmptyRow(false);
        int rowNo = analysisContext.readRowHolder().getRowIndex() + 1; // Excel行号
        if (ZbExcelFieldUtil.isLineNullValue(orderExcelImport)) {
            this.totalCount--;
            return;
        }
        // 校验字段的空值 & 字段长度值
        if (checkEmpty(rowNo, orderExcelImport)) {
            sendMessage();
            return;
        }
        // 校验数据是否重复
        if (checkDataRepeat(rowNo, orderExcelImport)) {
            sendMessage();
            return;
        }
        Map<String, Object> mapKey = getCacheData();
        // 品牌商家
        if (null == mapKey.get("factory_" + orderExcelImport.getFactory())) {
            message.append("A").append(rowNo).append("单元 品牌商家【" + orderExcelImport.getFactory() + "】不存在系统中，请检查后重试").append("</br>");
            orderExcelImport.setExcelMsg("品牌商家【" + orderExcelImport.getFactory() + "】不存在系统中，请检查后重试");
            this.importFailt.add(orderExcelImport);
            sendMessage();
            return;
        }
        ZjFactory factory = JSON.parseObject(JSON.toJSONString(mapKey.get("factory_" + orderExcelImport.getFactory())), ZjFactory.class);
        // 校验商品信息
        ViewGoods viewGoods = checkGoodsExist(rowNo, mapKey, orderExcelImport);
        if (null == viewGoods) {
            sendMessage();
            return;
        }
        // 工单客户
        ZjUser user = getUserData(mapKey, orderExcelImport);
        // 编码数据
        if (checkCodeData(rowNo, viewGoods, user, orderExcelImport)) {
            sendMessage();
            return;
        }
        // 工单类型
        if (null == mapKey.get("order_module_" + orderExcelImport.getModule())) {
            this.importFailt.add(orderExcelImport);
            message.append("L").append(rowNo).append("单元 工单类型【" + orderExcelImport.getModule() + "】不存在系统中，请检查后重试").append("</br>");
            orderExcelImport.setExcelMsg("工单类型【" + orderExcelImport.getModule() + "】不存在系统中，请检查后重试");
            this.importFailt.add(orderExcelImport);
            sendMessage();
            return;
        }
        ZjWorkModule module = JSON.parseObject(JSON.toJSONString(mapKey.get("order_module_" + orderExcelImport.getModule())), ZjWorkModule.class);

        // 工单等级
        ZjWorkLevel level = null;
        if (null != mapKey.get("order_level_" + orderExcelImport.getLevel())) {
            level = JSON.parseObject(JSON.toJSONString(mapKey.get("order_level_" + orderExcelImport.getLevel())), ZjWorkLevel.class);
        } else {
            level = new ZjWorkLevel();
            level.setId(IdWorker.getId());
            level.setCustAccId(this.loginInfo.getCustAccId());
            level.setName(orderExcelImport.getLevel());
            level.setColor("");
            level.setWeight(0);
            level.setDefaultLevel(false);
            level.setDisalbed(false);
            this.workLevelList.add(level);
            mapKey.put("order_level_" + orderExcelImport.getLevel(), level);
        }
        // 服务商
        ZjNetwork network = null;
        ViewNetworkEmpDetail networkEmpManager = null;
        ViewNetworkEmpDetail networkEmpDetail = null;
        if (StringUtils.isNotBlank(orderExcelImport.getNetwork())) {
            if (null == mapKey.get("order_network_" + orderExcelImport.getNetwork())) {
                message.append("P").append(rowNo).append("单元 服务商【" + orderExcelImport.getNetwork() + "】不存在系统中，派单失败，但不影响工单导入，导入后请手动派单").append("</br>");
                sendMessage();
            }
            network = JSON.parseObject(JSON.toJSONString(mapKey.get("order_network_" + orderExcelImport.getNetwork())), ZjNetwork.class);
            if (null != network) {
                networkEmpManager = JSON.parseObject(JSON.toJSONString(mapKey.get("order_network_manager_" + network.getId())), ViewNetworkEmpDetail.class);
            }
        }
        // 工程师
        if (StringUtils.isNotBlank(orderExcelImport.getEngineer())) {
            // 判断服务商是否为空
            if (null == network) {
                message.append("P").append(rowNo).append("单元 工单指派工程师，因服务商为不存在系统中或没有指定服务商，派工失败，但不影响工单导入，导入后请手动派单与派工").append("</br>");
                sendMessage();
            } else {
                if (null == mapKey.get("order_network_engineer_" + network.getId() + "_" + orderExcelImport.getEngineer())) {
                    message.append("Q").append(rowNo).append("单元 工程师【" + orderExcelImport.getEngineer() + "】不存在系统中，派工失败，但不影响工单导入，导入后请手动派工").append("</br>");
                    sendMessage();
                }
                networkEmpDetail = JSON.parseObject(JSON.toJSONString(mapKey.get("order_network_engineer_" + network.getId() + "_" +orderExcelImport.getEngineer())), ViewNetworkEmpDetail.class);
            }
        }
        // 客服
        Long empId = null;
        if (StringUtils.isNotBlank(orderExcelImport.getEmp())) {
            if (null == mapKey.get("order_service_emp_" + orderExcelImport.getEmp())) {
                message.append("R").append(rowNo).append("单元 客服【" + orderExcelImport.getEmp() + "】不存在系统中，分配客服失败，但不影响工单导入，导入后请手动分配客服").append("</br>");
                sendMessage();
            }
            empId = (Long) mapKey.get("order_service_emp_" + orderExcelImport.getEmp());
        }

        ZjFactoryOrderModuleSettlement factoryOrderModuleSettlement = null;
        if (null != mapKey.get("order_factory_module_settlement_" + factory.getId() + "_" + module.getId())) {
            factoryOrderModuleSettlement = JSON.parseObject(JSON.toJSONString(mapKey.get("order_factory_module_settlement_" +  + factory.getId() + "_" + module.getId())), ZjFactoryOrderModuleSettlement.class);
        }
        RedisUtil.setCache(this.CACHE_IMPORT_DATA_REDIS_KEY, JSON.toJSONString(mapKey));
        // 工单数据
        setOrderData(factory, empId, module, factoryOrderModuleSettlement, level.getId(), user.getId(), network, networkEmpManager, networkEmpDetail, orderExcelImport);
        if (this.orderList.size() >= BATCH_COUNT) {
            excuteSave();
        }
        sendMessage();
    }

    /**
     * 设置工单数据
     * @param factory 品牌商家
     * @param levelId 工单等级ID
     * @param userId 客户ID
     * @param orderExcelImport
     */
    private void setOrderData(ZjFactory factory, Long empId, ZjWorkModule module, ZjFactoryOrderModuleSettlement orderModuleSettlement, Long levelId, Long userId,
                              ZjNetwork network, ViewNetworkEmpDetail networkEmpManager, ViewNetworkEmpDetail networkEmpDetail, OrderExcelImport orderExcelImport) {
        ZjWorkOrder order = new ZjWorkOrder();
        order.setId(IdWorker.getId());
        order.setCustAccId(this.loginInfo.getCustAccId());
        order.setFactoryId(factory.getId());
        order.setCode(StringUtils.isNotBlank(orderExcelImport.getWorkNo())? orderExcelImport.getWorkNo() : ZbOrderNoUtil.importOrderNo(this.loginInfo.getCustAccId()));
        order.setStatus(orderExcelImport.getStatus());
        order.setArchived(false);
        order.setModuleId(module.getId());
        order.setEmpId(null == empId? 0L : empId);
        order.setAssignEmp(order.getEmpId() > 0);
        order.setAssignEmpTime(order.getAssignEmp()? new Date() : null);
        order.setNetworkId(0L);
        order.setNetworkEmpId(0L);
        order.setEndTime(null != orderExcelImport.getEndTime()? orderExcelImport.getEndTime() : null);
        order.setNewAdvance(0);
        order.setWaitCopeEvent(0);
        order.setOverinsured(null != orderExcelImport.getOverinsured() && orderExcelImport.getOverinsured());
        order.setReminderNum(0);
        order.setWarrantyDay(null == orderExcelImport.getWarrantyDay()? module.getWarrantyDay() : orderExcelImport.getWarrantyDay());
        order.setSource(WorkConstant.WORK_SOURCE_5);
        order.setWorkLevelId(levelId);
        order.setAllInclusiveFee(null == orderModuleSettlement || orderModuleSettlement.getAllInclusiveFee());
        order.setModulePrice(null != orderModuleSettlement? orderModuleSettlement.getPrice() : order.getOverinsured()? module.getOutSourcingPrice() : module.getInSourcingPrice());
        order.setNetworkModulePrice(new BigDecimal("0.0"));
        order.setEndOrder(order.getStatus() == WorkConstant.WORK_STATUS_4);
        order.setSettlementStatus(WorkConstant.WORK_SETTLEMENT_STATUS_0);
        order.setWithdrawFreezeDay(0);
        order.setComment(false);
        order.setChangeOrder(false);
        order.setSuspendStatus(0);
        order.setFactoryRemark("");
        order.setCreateEmpType(1);
        order.setCreateFactory("");
        order.setCreateEmpId(this.loginInfo.getId());
        order.setCreateEmp(this.loginInfo.getName());
        order.setUpdateEmpId(this.loginInfo.getId());
        order.setUpdateEmp(this.loginInfo.getName());
        order.setGmtCreate(null != orderExcelImport.getCreateTime()? orderExcelImport.getCreateTime() : null);
        this.logVos.add(new WorkLogVo(this.loginInfo, order.getId(), "工单导入"));
        if (StringUtils.isNotBlank(orderExcelImport.getEmp()) && null == empId) {
            this.logVos.add(new WorkLogVo(this.loginInfo, order.getId(), "工单导入并分配客服", "分配客服失败，客服不存在系统中，请手动分配"));
        }
        // 派单失败记录
        if (StringUtils.isNotBlank(orderExcelImport.getNetwork()) && null == network) {
            this.logVos.add(new WorkLogVo(this.loginInfo, order.getId(), "工单导入并派单", "派单失败，派单指定的的服务商 ["+ orderExcelImport.getNetwork() +"] 不存在，请手动派单"));
        }
        // 派工失败记录
        if (StringUtils.isNotBlank(orderExcelImport.getEngineer())) {
            if (StringUtils.isBlank(orderExcelImport.getNetwork())) {
                this.logVos.add(new WorkLogVo(this.loginInfo, order.getId(), "工单导入并派工", "派工失败，没有指定服务商，请指定服务商后再派工"));
            }
            if (null == networkEmpDetail) {
                this.logVos.add(new WorkLogVo(this.loginInfo, order.getId(), "工单导入并派工", "派工失败，派工的工程师 ["+ orderExcelImport.getEngineer() +"] 不存在，请手动派工"));
            }
        }
        // 服务商
        if (null != network) {
            this.logVos.add(new WorkLogVo(this.loginInfo, order.getId(), "工单导入并派单", "服务工单已派单服务商["+ network.getName() +"]，待服务商处理"));
            this.networkLogVos.add(new WorkLogVo(this.loginInfo.getCustAccId(), null != networkEmpManager ? networkEmpManager.getAccountName() : "", order.getId(), "服务商确认接单", "服务商已自动确认接单，等待派工"));
            order.setNetworkId(network.getId());
//            order.setStatus(WorkConstant.WORK_STATUS_3);

            ZjWorkDispatchNetwork dispatchNetwork = new ZjWorkDispatchNetwork();
            dispatchNetwork.setId(IdWorker.getId());
            dispatchNetwork.setCustAccId(this.loginInfo.getCustAccId());
            dispatchNetwork.setWorkId(order.getId());
            dispatchNetwork.setNetworkId(network.getId());
            dispatchNetwork.setStatus(order.getStatus() == WorkConstant.WORK_STATUS_4 ? WorkConstant.DISPATCH_NETWORK_STATUS_6 : WorkConstant.DISPATCH_NETWORK_STATUS_2);
            dispatchNetwork.setTransferOrderWaitCheck(false);
            dispatchNetwork.setDispatchTime(new Date());
            dispatchNetwork.setReceivingOrderTime(new Date());
            dispatchNetwork.setRemark("");
            // 工程师
            if (null != networkEmpDetail) {
                this.networkLogVos.add(new WorkLogVo(this.loginInfo.getCustAccId(), null != networkEmpManager ? networkEmpManager.getAccountName() : "", order.getId(), "服务商派工", "服务商已派工程师["+networkEmpDetail.getAccountName()+"]，待工程师处理"));
                this.networkLogVos.add(new WorkLogVo(this.loginInfo.getCustAccId(), networkEmpDetail.getAccountName(), order.getId(), "工程师确认接单", "工程师已自动确认接单并处理中"));
                order.setNetworkEmpId(networkEmpDetail.getId());

                ZjWorkDispatchEngineer dispatchEngineer = new ZjWorkDispatchEngineer();
                dispatchEngineer.setId(IdWorker.getId());
                dispatchEngineer.setCustAccId(this.loginInfo.getCustAccId());
                dispatchEngineer.setWorkId(order.getId());
                dispatchEngineer.setNetworkId(network.getId());
                dispatchEngineer.setNetworkEmpId(networkEmpDetail.getId());
                dispatchEngineer.setStatus(order.getStatus() == WorkConstant.WORK_STATUS_4 ? WorkConstant.DISPATCH_ENGINEER_STATUS_4 : WorkConstant.DISPATCH_ENGINEER_STATUS_2);
                dispatchEngineer.setDispatchTime(ZbDateConvertUtil.dateToDateStr(new Date()));
                dispatchEngineer.setReceivingOrderTime(ZbDateConvertUtil.dateToDateStr(new Date()));
                dispatchEngineer.setReservation(false);
                dispatchEngineer.setReservationDate("");
                dispatchEngineer.setReservationStartTime("");
                dispatchEngineer.setReservationEndTime("");
                dispatchEngineer.setNetworkEmpFinishTime("");
                dispatchEngineer.setDispatchRemark("");
                dispatchEngineer.setRemark("");
                dispatchEngineer.setCallPhoneQty(0);
                dispatchEngineer.setCallPhoneTime("");
                dispatchEngineer.setWriteCallPhoneResult(false);
                dispatchEngineer.setSignIn(false);
                this.dispatchEngineerList.add(dispatchEngineer);

                dispatchNetwork.setStatus(WorkConstant.DISPATCH_NETWORK_STATUS_4);
            }
            this.dispatchNetworkList.add(dispatchNetwork);
        }
//        if (order.getStatus() == WorkConstant.WORK_STATUS_3 && order.getNetworkId() == 0) {
//            order.setStatus(WorkConstant.WORK_STATUS_1);
//        }
        this.orderList.add(order);

        ZjWorkDetail detail = new ZjWorkDetail();
        detail.setId(order.getId());
        detail.setCustAccId(this.loginInfo.getCustAccId());
        detail.setOneTypeId(0L);
        detail.setTwoTypeId(0L);
        detail.setThreeTypeId(0L);
        detail.setOneWayId(0L);
        detail.setTwoWayId(0L);
        detail.setThreeWayId(0L);
        detail.setContent(null == orderExcelImport.getContent()? "" : orderExcelImport.getContent());
        detail.setNoReviewApplyWorkFeeNum(0);
        detail.setNoReviewApplyWorkSpareNum(0);
        detail.setEndOrderApply(false);
        detail.setCancelOrderApply(false);
        detail.setChangeNetworkApply(false);
        detail.setDispatchEmpId(0L);
        detail.setReservation(false);
        detail.setStatementVerifCode(RandomUtil.randomNumber6());
        detail.setCollectCustomerPriceVoucher("");
        this.workDetailList.add(detail);

        ZjWorkUser workUser = new ZjWorkUser();
        workUser.setId(order.getId());
        workUser.setCustAccId(this.loginInfo.getCustAccId());
        workUser.setHelpOtherCreateOrder(false);
        workUser.setCreateOrderUserId(0L);
        workUser.setUserId(userId);
        workUser.setName(orderExcelImport.getUsername());
        workUser.setPhone(orderExcelImport.getUserPhone());
        workUser.setOtherPhone("");
        workUser.setProvince(orderExcelImport.getProvince());
        workUser.setCity(orderExcelImport.getCity());
        workUser.setArea(orderExcelImport.getArea());
        workUser.setTown("");
        workUser.setAddress(orderExcelImport.getAddress());
        this.workUserList.add(workUser);

        ZjWorkGoods workGoods = new ZjWorkGoods();
        workGoods.setId(IdWorker.getId());
        workGoods.setCustAccId(this.loginInfo.getCustAccId());
        workGoods.setWorkId(order.getId());
        workGoods.setGoodsId(this.globalCode.getGoodsId());
        workGoods.setGoodsSpecId(this.globalCode.getGoodsSpecId());
        workGoods.setBuyTime(this.globalCode.getWarrantyStartTime());
        workGoods.setEndTime(this.globalCode.getWarrantyEndTime());
        workGoods.setQty(1);
        this.workGoodsList.add(workGoods);

        ZjWorkGoodsCode goodsCode = new ZjWorkGoodsCode();
        goodsCode.setId(IdWorker.getId());
        goodsCode.setCustAccId(this.loginInfo.getCustAccId());
        goodsCode.setWorkId(order.getId());
        goodsCode.setWorkGoodsId(workGoods.getId());
        goodsCode.setCodeId(this.globalCode.getId());
        goodsCode.setCode(this.globalCode.getSecurityCode());
        this.workGoodsCodeList.add(goodsCode);
    }

    /**
     * 获取客户
     * @param mapKey
     * @param orderExcelImport
     * @return
     */
    private ZjUser getUserData(Map<String, Object> mapKey, OrderExcelImport orderExcelImport) {
        ZjUser user = null;
        if (null != mapKey.get("user_" + orderExcelImport.getUserPhone())) {
            user = JSON.parseObject(JSON.toJSONString(mapKey.get("user_" + orderExcelImport.getUserPhone())), ZjUser.class);
        } else {
            user = new ZjUser();
            user.setId(IdWorker.getId());
            user.setCustAccId(loginInfo.getCustAccId());
            user.setPhone(orderExcelImport.getUserPhone());
            user.setAccount("ZB" + BCryptUtil.generatorSalt().substring(10, 20));
            user.setSalt(BCryptUtil.generatorSalt());
            user.setPassword(BCryptUtil.encryPassword(user.getPhone().substring(5), user.getSalt()));
            user.setCode(userSet.getCode() + RandomUtil.random16());
            user.setName(orderExcelImport.getUsername());
            user.setNickname(orderExcelImport.getUsername());
            user.setStatus(0);
            user.setAvatar("");
            user.setMoney(new BigDecimal("0.0"));
            user.setUserTypeId(0L);
            user.setUserType("");
            user.setLevelId(null == userSet.getLevelId()? 0L : userSet.getLevelId());
            user.setLevel("");
            user.setSelectKnowledgeAuthor(false);
            user.setCreateEmpId(loginInfo.getId());
            user.setUpdateEmpId(loginInfo.getId());
            this.userList.add(user);
            mapKey.put("user_" + orderExcelImport.getUserPhone(), user);

            ZjUserContact contact = new ZjUserContact();
            contact.setId(IdWorker.getId());
            contact.setCustAccId(loginInfo.getCustAccId());
            contact.setUserId(user.getId());
            contact.setMainContact(true);
            contact.setUsername(orderExcelImport.getUsername());
            contact.setPhone(orderExcelImport.getUserPhone());
            contact.setEmail("");
            contact.setProvince(orderExcelImport.getProvince());
            contact.setCity(orderExcelImport.getCity());
            contact.setArea(orderExcelImport.getArea());
            contact.setTown("");
            contact.setAddress(orderExcelImport.getAddress());
            userContactList.add(contact);
        }
        return user;
    }

    private Map<String, Object> getCacheData() {
        Map<String, Object> cacheData = null;
        Object byKey = RedisUtil.getByKey(this.CACHE_IMPORT_DATA_REDIS_KEY);
        if (null == byKey) {
            return new HashMap<>();
        }
        cacheData = JSON.parseObject((String) byKey, Map.class);
        return cacheData;
    }

    /**
     * 校验一物一码并设置数据
     * @param rowNo
     * @param viewGoods
     * @param user
     * @param orderExcelImport
     * @return
     */
    private boolean checkCodeData(int rowNo, ViewGoods viewGoods, ZjUser user, OrderExcelImport orderExcelImport) {
        // 编码不为空
        if (StringUtils.isNotBlank(orderExcelImport.getCode())) {
            ZjCode code = this.codeService.getByCode(this.loginInfo.getCustAccId(), orderExcelImport.getCode());
            if (null != code) {
                if (!Objects.equals(code.getGoodsId(), viewGoods.getId()) || !Objects.equals(code.getGoodsSpecId(), viewGoods.getSpecId())) {
                    this.importFailt.add(orderExcelImport);
                    this.message.append("G").append(rowNo).append("单元 报单商品一物一码与报单商品型号、规格绑定的一物一码不匹配！").append("</br>");
                    orderExcelImport.setExcelMsg("报单商品一物一码与报单商品型号、规格绑定的一物一码不匹配");
                    return true;
                }
                // 校验一物一码是否关联绑定，已绑定的与现客户是否一致
                ZjCodeUserRegister userRegister = this.codeUserRegisterService.getById(code.getId());
                // 已登记绑定
                if (null != userRegister) {
                    if (!Objects.equals(userRegister.getUserId(), user.getId())) {
                        this.importFailt.add(orderExcelImport);
                        this.message.append("G").append(rowNo).append("单元 报单商品一物一码与报单客户登记绑定的信息不匹配！").append("</br>");
                        orderExcelImport.setExcelMsg("报单商品一物一码与报单客户登记绑定的信息不匹配");
                        return true;
                    }
                } else {
                    // 未登记
                    ZjCode updateCode = new ZjCode();
                    updateCode.setId(code.getId());
                    updateCode.setWarrantyStartTime(null != orderExcelImport.getGoodsBuyTime()? orderExcelImport.getGoodsBuyTime() : new Date());
                    updateCode.setWarrantyEndTime(DateUtils.addDays(updateCode.getWarrantyStartTime(), code.getWarrantyDay()));
                    updateCode.setStatus(updateCode.getWarrantyEndTime().after(new Date())? CodeConstant.CODE_STATUS_2 : CodeConstant.CODE_STATUS_3);
                    if (!code.getActiva()) {
                        updateCode.setActiva(true);
                        updateCode.setActivaTime(new Date());
                    }
                    if (code.getStoreStatus() != 5) updateCode.setStoreStatus(CodeConstant.STORE_STATUS_5);
                    this.updateCodeList.add(updateCode);

                    ZjCodeInfo codeInfo = new ZjCodeInfo();
                    codeInfo.setId(code.getId());
                    codeInfo.setRegister(true);
                    codeInfo.setRegisterTime(new Date());
                    this.updateCodeInfoList.add(codeInfo);
                    setCodeUserRegister(code.getId(), user.getId(), orderExcelImport);
                    this.codeLogList.add(new CodeLogExtend(this.loginInfo, CodeConstant.CODE_LOG_TYPE_1, code.getId(), "工单Excel导入报单创建", "导入报单商品一物一码并与客户信息登记绑定"));
                }
                this.globalCode = code;
                return false;
            }
        }
        // 创建编码
        setCodeBatch(viewGoods);
        setCode(viewGoods, orderExcelImport);
        setCodeUserRegister(this.globalCode.getId(), user.getId(), orderExcelImport);
        this.codeLogList.add(new CodeLogExtend(this.loginInfo, CodeConstant.CODE_LOG_TYPE_1, this.globalCode.getId(), "工单Excel导入报单创建", "导入报单商品一物一码并与客户信息登记绑定"));
        return false;
    }

    /**
     * 编码批次数据
     * @param viewGoods
     */
    private void setCodeBatch(ViewGoods viewGoods) {
        Object byKey = RedisUtil.getByKey(code_batch_goods_data_key);
        Map<String, Object> codeBatchGoodstMap = null;
        if (null == byKey) {
            codeBatchGoodstMap = new HashMap<>();
        } else {
            codeBatchGoodstMap = JSON.parseObject((String) byKey, HashMap.class);
        }
        ZjCodeBatch codeBatch = JSON.parseObject(JSON.toJSONString(codeBatchGoodstMap.get("code_batch_" + viewGoods.getId() + "_" + viewGoods.getSpecId())), ZjCodeBatch.class);
        if (null == codeBatch || null == this.codeBatchId) {
            codeBatch = new ZjCodeBatch();
            codeBatch.setId(IdWorker.getId());
            codeBatch.setCustAccId(this.loginInfo.getCustAccId());
            codeBatch.setType(1);
            codeBatch.setName("报单导入并创建一物一码");
            codeBatch.setCode((StringUtils.isBlank(this.codeSet.getBatchPrefix()) ? "" : this.codeSet.getBatchPrefix()) + RandomUtil.dateRandom14());
            codeBatch.setQty(1);
            codeBatch.setCodeSource(CodeConstant.CODE_SOURCE_3);
            codeBatch.setDisabled(false);
            codeBatch.setCreateEmpId(this.loginInfo.getId());
            codeBatch.setCreateEmp(this.loginInfo.getName());
            codeBatch.setUpdateEmpId(this.loginInfo.getId());
            codeBatch.setUpdateEmp(this.loginInfo.getName());
            this.addCodeBatchList.add(codeBatch);
            this.codeBatchId = codeBatch.getId();
            codeBatchGoodstMap.put("code_batch_" + viewGoods.getId() + "_" + viewGoods.getSpecId(), codeBatch);
        } else {
            if (CollectionUtil.isNotEmpty(this.addCodeBatchList)) {
                for (ZjCodeBatch batch : this.addCodeBatchList) {
                    batch.setQty(batch.getQty() +1);
                    codeBatchGoodstMap.put("code_batch_" + viewGoods.getId() + "_" + viewGoods.getSpecId(), batch);
                }
            } else {
                codeBatch.setQty(codeBatch.getQty() +1);
                this.updateCodeBatchList.add(codeBatch);
                codeBatchGoodstMap.put("code_batch_" + viewGoods.getId() + "_" + viewGoods.getSpecId(), codeBatch);
            }
        }
        ZjCodeBatchGoods codeBatchGoods = JSON.parseObject(JSON.toJSONString(codeBatchGoodstMap.get("code_batch_goods_" + viewGoods.getId() + "_" + viewGoods.getSpecId())), ZjCodeBatchGoods.class);
        if (null == codeBatchGoods) {
            codeBatchGoods = new ZjCodeBatchGoods();
            codeBatchGoods.setId(IdWorker.getId());
            codeBatchGoods.setCustAccId(this.loginInfo.getCustAccId());
            codeBatchGoods.setBatchId(this.codeBatchId);
            codeBatchGoods.setGoodsId(viewGoods.getId());
            codeBatchGoods.setGoodsSpecId(viewGoods.getSpecId());
            codeBatchGoods.setQty(1);
            codeBatchGoods.setWarrantyDay(viewGoods.getWarrantyDay());
            this.addCodeBatchGoodsList.add(codeBatchGoods);
            codeBatchGoodstMap.put("code_batch_goods_" + viewGoods.getId() + "_" + viewGoods.getSpecId(), codeBatchGoods);
        } else {
            if (this.addCodeBatchGoodsList.stream().anyMatch(f -> Objects.equals(f.getGoodsId(), viewGoods.getId()) && Objects.equals(f.getGoodsSpecId(), viewGoods.getSpecId()))) {
                for (ZjCodeBatchGoods batchGoods : this.addCodeBatchGoodsList) {
                    if (Objects.equals(batchGoods.getId(), codeBatchGoods.getId())) {
                        batchGoods.setQty(batchGoods.getQty() +1);
                        codeBatchGoodstMap.put("code_batch_goods_" + viewGoods.getId() + "_" + viewGoods.getSpecId(), batchGoods);
                        break;
                    }
                }
            } else {
                codeBatchGoods.setQty(codeBatchGoods.getQty() + 1);
                this.updateCodeBatchGoodsList.add(codeBatchGoods);
                codeBatchGoodstMap.put("code_batch_goods_" + viewGoods.getId() + "_" + viewGoods.getSpecId(), codeBatchGoods);
            }
        }
        this.codebatchGoodsId = codeBatchGoods.getId();
        RedisUtil.setCache(code_batch_goods_data_key, JSON.toJSONString(codeBatchGoodstMap));
    }

    /**
     * 编码数据
     * @param viewGoods
     * @param orderExcelImport
     */
    private void setCode(ViewGoods viewGoods, OrderExcelImport orderExcelImport) {
        ZjCode addCode = new ZjCode();
        addCode.setId(IdWorker.getId());
        addCode.setCustAccId(this.loginInfo.getCustAccId());
        addCode.setBatchId(this.codeBatchId);
        addCode.setBatchGoodsId(this.codebatchGoodsId);
        addCode.setType(1);
        addCode.setGoodsId(viewGoods.getId());
        addCode.setGoodsSpecId(viewGoods.getSpecId());
        if (StringUtils.isBlank(orderExcelImport.getCode())) {
            addCode.setSecurityCode((StringUtils.isBlank(this.codeSet.getCodePrefix()) ? "" :
                    this.codeSet.getCodePrefix()) + CodeUtil.generatorCode(this.codeSet.getCodeRule(), viewGoods.getCreateTime()));
        } else {
            addCode.setSecurityCode(orderExcelImport.getCode());
        }
        addCode.setStoreCode((StringUtils.isBlank(this.codeSet.getStorehousePrefix())? "" :
                this.codeSet.getStorehousePrefix()) + CodeUtil.generatorCode(this.codeSet.getStorehouseRule(), viewGoods.getCreateTime()));
        addCode.setWarrantyDay(viewGoods.getWarrantyDay());
        addCode.setWarrantyStartTime(null != orderExcelImport.getGoodsBuyTime()? orderExcelImport.getGoodsBuyTime() : new Date());
        addCode.setWarrantyEndTime(DateUtils.addDays(addCode.getWarrantyStartTime(), addCode.getWarrantyDay()));
        addCode.setStatus(addCode.getWarrantyEndTime().after(new Date())? CodeConstant.CODE_STATUS_2 : CodeConstant.CODE_STATUS_3);
        addCode.setActiva(true);
        addCode.setActivaTime(new Date());
        addCode.setStoreId(0L);
        addCode.setStorePositionId(0L);
        addCode.setStoreStatus(CodeConstant.STORE_STATUS_5);
        addCode.setOutStoreActiva(false);
        addCode.setOutStoreWarranty(false);
        addCode.setCodeSource(CodeConstant.CODE_SOURCE_3);
        addCode.setNetworkId(0L);
        addCode.setNetwork("");
        addCode.setDisabled(false);
        addCode.setCreateEmpId(this.loginInfo.getId());
        addCode.setCreateEmp(this.loginInfo.getName());
        addCode.setUpdateEmpId(this.loginInfo.getId());
        addCode.setUpdateEmp(this.loginInfo.getName());
        this.addCodeList.add(addCode);

        ZjCodeInfo codeInfo = new ZjCodeInfo();
        codeInfo.setId(addCode.getId());
        codeInfo.setCustAccId(this.loginInfo.getCustAccId());
        codeInfo.setRegister(true);
        codeInfo.setRegisterTime(new Date());
        codeInfo.setSelectNum(0);
        codeInfo.setInboundCode("");
        codeInfo.setOutboundCode("");
        this.addCodeInfoList.add(codeInfo);

        this.globalCode = addCode;
    }

    /**
     * 编码登记并绑定客户
     * @param codeId 编码ID
     * @param userId 客户ID
     * @param orderExcelImport
     */
    private void setCodeUserRegister(Long codeId, Long userId, OrderExcelImport orderExcelImport) {
        ZjCodeUserRegister userRegister = new ZjCodeUserRegister();
        userRegister.setId(codeId);
        userRegister.setCustAccId(this.loginInfo.getCustAccId());
        userRegister.setUserId(userId);
        userRegister.setName(orderExcelImport.getUsername());
        userRegister.setPhone(orderExcelImport.getUserPhone());
        userRegister.setProvince(orderExcelImport.getProvince());
        userRegister.setCity(orderExcelImport.getCity());
        userRegister.setArea(orderExcelImport.getArea());
        userRegister.setTown("");
        userRegister.setAddress(orderExcelImport.getAddress());
        this.userRegisterList.add(userRegister);
    }

    /**
     * 校验报单商品
     * @param rowNo
     * @param mapKey
     * @param orderExcelImport
     * @return
     */
    private ViewGoods checkGoodsExist(int rowNo, Map<String, Object> mapKey, OrderExcelImport orderExcelImport) {
        ViewGoods viewGoods = null;
        if (null == mapKey.get("goods_product_model_" + orderExcelImport.getGoodsModel())) {
            this.importFailt.add(orderExcelImport);
            this.message.append("I").append(rowNo).append("单元 报单商品型号的数据不存在，请检查后重新导入").append("</br>");
            orderExcelImport.setExcelMsg("报单商品型号的数据不存在，请检查后重新导入");
            return null;
        } else {
            viewGoods = JSON.parseObject(JSON.toJSONString(mapKey.get("goods_product_model_" + orderExcelImport.getGoodsModel())), ViewGoods.class);
        }
        if (!Objects.equals(viewGoods.getSpecName(), orderExcelImport.getGoodsSpec())) {
            this.importFailt.add(orderExcelImport);
            this.message.append("J").append(rowNo).append("单元 报单商品规格与报单商品型号不匹配或数据不存在，请检查后重新导入").append("</br>");
            orderExcelImport.setExcelMsg("报单商品规格与报单商品型号不匹配或数据不存在，请检查后重新导入");
            return null;
        }
        return viewGoods;
    }

    /**
     * 校验数据是否重复
     * @param rowNo
     * @param orderExcelImport
     * @return
     */
    private boolean checkDataRepeat(int rowNo, OrderExcelImport orderExcelImport) {
        boolean isDataRepeat = false;
        Object byKey = RedisUtil.getByKey(check_data_repeat_key);
        Map<String, Object> dataRepeatMap = JSON.parseObject((String) byKey, HashMap.class);
        if (null == dataRepeatMap) {
            dataRepeatMap = new HashMap<>();
        }
        // 商品一物一码
        if (StringUtils.isNotBlank(orderExcelImport.getCode())) {
            if (null != dataRepeatMap.get("goods_code_" + orderExcelImport.getCode())) {
                this.message.append("H").append(rowNo).append("单元 商品一物一码已重复填写").append("</br>");
                orderExcelImport.setExcelMsg("商品一物一码已重复填写");
                isDataRepeat = true;
            } else {
                dataRepeatMap.put("goods_code_" + orderExcelImport.getCode(), true);
            }
        }
        // 工单单号
        if (StringUtils.isNotBlank(orderExcelImport.getWorkNo())) {
            // 是否重复填写
            if (null != dataRepeatMap.get("work_code_" + orderExcelImport.getWorkNo())) {
                this.message.append("M").append(rowNo).append("单元 工单单号已重复填写").append("</br>");
                orderExcelImport.setExcelMsg("工单单号已重复填写");
                isDataRepeat = true;
            } else {
                // 判断是否重复
                if (null != this.workOrderService.existCodeByCustAccId(this.loginInfo.getCustAccId(), orderExcelImport.getWorkNo())){
                    this.message.append("M").append(rowNo).append("单元 工单单号已存在系统中，禁止重复").append("</br>");
                    orderExcelImport.setExcelMsg("工单单号已存在系统中，禁止重复");
                    isDataRepeat = true;
                }
            }
            dataRepeatMap.put("work_code_" + orderExcelImport.getWorkNo(), true);
        }
        RedisUtil.setCache(check_data_repeat_key, JSON.toJSONString(dataRepeatMap));
        if (isDataRepeat) {
            this.importFailt.add(orderExcelImport);
        }
        return isDataRepeat;
    }

    /**
     * 校验字段的空值 & 字段长度值
     * @param rowNo
     * @param orderExcelImport
     * @return
     */
    private boolean checkEmpty(int rowNo, OrderExcelImport orderExcelImport) {
        if (StringUtils.isBlank(orderExcelImport.getFactory())) {
            message.append("A").append(rowNo).append("单元 所属品牌商家名称不能为空").append("</br>");
            orderExcelImport.setExcelMsg("所属品牌商家名称不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getUsername())) {
            message.append("B").append(rowNo).append("单元 客户名称不能为空").append("</br>");
            orderExcelImport.setExcelMsg("客户名称不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getUsername().length() > 100) {
            message.append("B").append(rowNo).append("单元 客户名称字符长度限制100个字符").append("</br>");
            orderExcelImport.setExcelMsg("客户名称字符长度限制100个字符");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (!VerificUtil.phoneVerific(orderExcelImport.getUserPhone())) {
            message.append("C").append(rowNo).append("单元 客户手机号不能为空或手机号格式错误").append("</br>");
            orderExcelImport.setExcelMsg("客户手机号不能为空或手机号格式错误");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getProvince())) {
            message.append("D").append(rowNo).append("单元 客户报单地址-省不能为空").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-省不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getProvince().length() > 50) {
            message.append("D").append(rowNo).append("单元 客户报单地址-省字符长度限制50个字符").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-省字符长度限制50个字符");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getCity())) {
            message.append("E").append(rowNo).append("单元 客户报单地址-市不能为空").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-市不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getCity().length() > 50) {
            message.append("E").append(rowNo).append("单元 客户报单地址-市字符长度限制50个字符").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-市字符长度限制50个字符");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getArea())) {
            message.append("F").append(rowNo).append("单元 客户报单地址-区/县不能为空").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-区/县不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getArea().length() > 50) {
            message.append("F").append(rowNo).append("单元 客户报单地址-区/县字符长度限制50个字符").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-区/县字符长度限制50个字符");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getAddress())) {
            message.append("G").append(rowNo).append("单元 客户报单地址-详细地址不能为空").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-详细地址不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getAddress().length() > 200) {
            message.append("G").append(rowNo).append("单元 客户报单地址-详细地址字符长度限制200个字符").append("</br>");
            orderExcelImport.setExcelMsg("客户报单地址-详细地址字符长度限制200个字符");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getGoodsModel())) {
            message.append("I").append(rowNo).append("单元 报单商品型号不能为空").append("</br>");
            orderExcelImport.setExcelMsg("报单商品型号不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getGoodsModel())) {
            message.append("J").append(rowNo).append("单元 报单商品规格不能为空").append("</br>");
            orderExcelImport.setExcelMsg("报单商品规格不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getModule())) {
            message.append("L").append(rowNo).append("单元 工单类型不能为空").append("</br>");
            orderExcelImport.setExcelMsg("工单类型不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (null == orderExcelImport.getStatus() || !Pattern.matches("^(1|3|4)$", orderExcelImport.getStatus().toString())) {
            message.append("N").append(rowNo).append("单元 工单状态参数不合法").append("</br>");
            orderExcelImport.setExcelMsg("工单状态参数不合法");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getStatus() == 4 && null == orderExcelImport.getEndTime()) {
            message.append("O").append(rowNo).append("单元 当前工单状态为[4(已完成)]，结单时间不能为空").append("</br>");
            orderExcelImport.setExcelMsg("当前工单状态为[4(已完成)]，结单时间不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isBlank(orderExcelImport.getLevel())) {
            message.append("M").append(rowNo).append("单元 工单等级不能为空").append("</br>");
            orderExcelImport.setExcelMsg("工单等级不能为空");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (orderExcelImport.getLevel().length() > 20) {
            message.append("M").append(rowNo).append("单元 工单等级长度限制20个字符以内").append("</br>");
            orderExcelImport.setExcelMsg("工单等级长度限制20个字符以内");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        if (StringUtils.isNotBlank(orderExcelImport.getContent()) && orderExcelImport.getContent().length() > 1000) {
            message.append("W").append(rowNo).append("单元 工单内容描述长度限制1000个字符").append("</br>");
            orderExcelImport.setExcelMsg("工单内容描述长度限制1000个字符");
            this.importFailt.add(orderExcelImport);
            return true;
        }
        return false;
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        RedisUtil.clearCache(check_data_repeat_key);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        RedisUtil.clearCache(this.check_data_repeat_key);
        RedisUtil.clearCache(this.code_batch_goods_data_key);
        if (CollectionUtil.isNotEmpty(this.orderList)) {
            excuteSave();
        }
        if (!this.isEndSend) {
            ProgressWebSocketServer.send(this.progressUuid, true, 100, this.totalCount, this.importFailt, this.message.toString());
            this.isEndSend = true;
        }
    }

    private void excuteSave() {
        String color = "#67C23A";
        this.batch_no++;
        this.message.append("<div style=color:").append(color).append(">解析完成，正在处理保存 [第 ").append(this.batch_no).append("批] 数据，请耐心等待...</div>");
        sendMessage();
        this.message.append("<div style=color:").append(color).append(">第 ").append(this.batch_no);
        TransactionStatus status = this.transactionManager.getTransaction(TransactionUtil.transactionDefinition());
        try {
            this.codeBatchService.saveExcelBatchCode(this.addCodeBatchList, this.updateCodeBatchList, this.addCodeBatchGoodsList, this.updateCodeBatchGoodsList);
            this.codeService.saveOrderExcelImportCode(this.addCodeList, this.updateCodeList, this.addCodeInfoList, this.updateCodeInfoList, this.codeLogList);
            if (CollectionUtil.isNotEmpty(this.userRegisterList)) this.codeUserRegisterService.saveBatch(this.userRegisterList);
            if (CollectionUtil.isNotEmpty(this.userList)) this.userService.saveBatch(this.userList);
            if (CollectionUtil.isNotEmpty(this.userContactList)) this.userContactService.saveBatch(this.userContactList);
            if (CollectionUtil.isNotEmpty(this.workLevelList)) this.workLevelService.saveBatch(this.workLevelList);
            this.workOrderService.saveBatch(this.orderList);
            this.workDetailService.saveBatch(this.workDetailList);
            this.workUserService.saveBatch(this.workUserList);
            this.workGoodsService.saveBatch(this.workGoodsList);
            this.workGoodsCodeService.saveBatch(this.workGoodsCodeList);
            if (CollectionUtil.isNotEmpty(this.dispatchNetworkList)) this.workDispatchNetworkService.saveBatch(this.dispatchNetworkList);
            if (CollectionUtil.isNotEmpty(this.dispatchEngineerList)) this.workDispatchEngineerService.saveBatch(this.dispatchEngineerList);
            WorkServiceLog.saveService(this.logVos);
            WorkServiceLog.saveNetwork(this.networkLogVos);
            this.transactionManager.commit(status);
            this.message.append(" 批导入成功</div>");
        }catch (Exception e) {
            e.printStackTrace();
            color = "#F56C6C";
            logger.error("工单数据第 {} 批导入失败，失败原因：{}", this.batch_no, e.getMessage());
            this.message.append(" 导入失败！原因：").append(e.getMessage()).append("</div>");
            this.transactionManager.rollback(status);
        }
        initData();
    }

    /**
     * 发送进度消息
     */
    private void sendMessage() {
        ProgressWebSocketServer.send(this.progressUuid, false, (1.0 * this.currentExcuteCount / this.excelTotalRowCount *100), this.importFailt, this.message.toString());
    }
}
